package com.guaoran.micro.services.spring.boot.auto.configuraton;

import com.guaoran.micro.services.spring.boot.auto.configuraton.enable.EnableScheduleAndCache;
import com.guaoran.micro.services.spring.boot.auto.configuraton.service.CacheService;
import com.guaoran.micro.services.spring.boot.auto.configuraton.service.ScheduleService;
import com.guaoran.micro.services.spring.boot.auto.configuraton.service.UserService;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.*;

import java.util.Collection;
import java.util.Set;

/**
 * @author : 孤傲然
 * @description : Enable 注解驱动 测试类
 * @desc : 虽然“模块装配”（注解模块驱动）需要手动触发，没有 SpringBoot 所提供的 “自动装配”的能力，但如果将“模块装配”和“自动装配”比作汽车驾驶，
 *      则 “模块装配” 属于 “手动挡” ，“自动装配” 属于 “自动挡”
 *
 * @README  springboot 中实现 Enable 注解驱动 ： 通过创建一个注解并{@link Import} 一个类即可，有三种体现形式
 * @one     通过 {@link Import} 注解导入标注{@link Configuration} 类
 * @two     通过 {@link Import} 注解导入实现{@link ImportSelector} 类
 * @three   通过 {@link Import} 注解导入实现{@link ImportBeanDefinitionRegistrar} 类
 *
 *
 * @Source {@link AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry, Object)} )} ->
 *  注册 {@link ConfigurationClassPostProcessor} ->
 *  {@link ConfigurationClassPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)} ->
 *  {@link ConfigurationClassPostProcessor#processConfigBeanDefinitions(BeanDefinitionRegistry)} ->
 *  {@link ConfigurationClassParser#parse(Set)}  ->
 *  {@link ConfigurationClassParser#processConfigurationClass(ConfigurationClass)} ->
 *  {@link ConfigurationClassParser#doProcessConfigurationClass(ConfigurationClass, ConfigurationClassParser.SourceClass)} ->
 *  Process any @Import annotations ,这里便包含以上的三种方式，这里是将bean对象取出进行下一步的注册bean {@link ConfigurationClassParser#processImports(ConfigurationClass, ConfigurationClassParser.SourceClass, Collection, boolean)} ->
 *  进行注册 {@link ConfigurationClassBeanDefinitionReader#loadBeanDefinitions(Set)}
 *
 * @date :2019/8/14 21:49
 */
@EnableScheduleAndCache
public class EnableAnnotationBootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(EnableAnnotationBootStrap.class);
        CacheService cacheService = context.getBean(CacheService.class);
        cacheService.cache();
        ScheduleService scheduleService = context.getBean(ScheduleService.class);
        scheduleService.schedule();
        UserService userService = (UserService) context.getBean("userService");
        userService.user();
    }
}
